package com.tuling.jucdemo.sync;

import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;

/**
 * @author :tangweiliang
 * @date : 2022/11/10 22:18
 * 未来的你会感谢现在努力的自己
 *
 * 测试 偏向锁，轻量级锁，重量级锁标记变化
 * 关闭延迟开启偏向锁： -XX:BiasedLockingStartupDelay=0
 * 无锁 001
 * 偏向锁 101
 * 轻量级锁 00
 * 重量级锁 10
 */
@Slf4j
public class LockEscalationDemo {
    public static void main(String[] args) throws InterruptedException {
        log.debug(ClassLayout.parseInstance(new Object()).toPrintable());

        //HotSpot 虚拟机在启动后有个 4s 的延迟才会对每个新建的对象开启偏向锁模式
        Thread.sleep(5000);
        Object object = new Object();
        //思考： 如果对象调用了hashCode,还会开启偏向锁模式嘛
        object.hashCode();
        log.debug(ClassLayout.parseInstance(object).toPrintable());

        new Thread(new Runnable(){
            @Override
            public void run() {
                log.debug(Thread.currentThread().getName()+"开始执行...\n"+ClassLayout.parseInstance(object).toPrintable());
                synchronized (object){
//                    try {
//                        object.wait(50);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
                    log.debug(Thread.currentThread().getName()+"获取锁执行中...\n"+ClassLayout.parseInstance(object).toPrintable());
                }
                log.debug(Thread.currentThread().getName()+"释放锁...\n"+ClassLayout.parseInstance(object).toPrintable());
            }
        },"thread1").start();

        //控制线程竞争时机
        Thread.sleep(1);

        new Thread(new Runnable() {
            @Override
            public void run() {
                log.debug(Thread.currentThread().getName()+"开始执行...\n"+ClassLayout.parseInstance(object).toPrintable());
                synchronized (object){
                    log.debug(Thread.currentThread().getName()+"获取锁执行中...\n"+ClassLayout.parseInstance(object).toPrintable());
                }
                log.debug(Thread.currentThread().getName()+"释放锁...\n"+ClassLayout.parseInstance(object).toPrintable());
            }
        },"thread2").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                log.debug(Thread.currentThread().getName()+"开始执行...\n"+ClassLayout.parseInstance(object).toPrintable());
                synchronized (object){
                    log.debug(Thread.currentThread().getName()+"获取锁执行中...\n"+ClassLayout.parseInstance(object).toPrintable());
                }
                log.debug(Thread.currentThread().getName()+"释放锁...\n"+ClassLayout.parseInstance(object).toPrintable());
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"thread3").start();


        Thread.sleep(5000);
        log.debug(ClassLayout.parseInstance(object).toPrintable());

    }
}
